<template>
  <div class="flowable-page">
    <!-- 左侧任务列表 -->
    <div class="task-list">
      <el-card shadow="hover" class="list-card">
        <h3>任务列表</h3>
        <el-table
          :key="tasks.length"
          :data="tasks"
          style="width: 100%"
          @row-click="handleTaskClick"
          highlight-current-row
        >
          <el-table-column prop="name" label="任务名称" width="160" />
          <el-table-column prop="assignee" label="执行人" width="100" />
          <el-table-column prop="createTime" label="创建时间" />
        </el-table>
      </el-card>
    </div>

    <!-- 右侧详情展示 -->
    <div class="task-detail">
      <el-card v-if="selectedTask" shadow="hover" class="detail-card">
        <div class="card-header">
          <h3>{{ selectedTask.name }}</h3>

          <!-- 认领按钮：仅当任务未被认领，且当前用户是主管或经理 -->
          <el-button
            v-if="showClaimButton"
            type="primary"
            size="small"
            @click="handleClaimTask"
          >
            认领任务
          </el-button>
        </div>

        <p><strong>流程实例(任务)ID：</strong>{{ selectedTask.id }}</p>
        <p><strong>Form定义ID：</strong>{{ form.id }}</p>
        <p><strong>执行人：</strong>{{ selectedTask.assignee }}</p>
        <p>
          <strong>创建时间：</strong
          >{{ formatTimeAgo(selectedTask.createTime) }}
        </p>

        <el-divider />

        <!-- 动态渲染表单 -->
        <div v-if="form && form.fields && form.fields.length">
          <h4>关联表单</h4>
          <!-- ① 有字段的情况：动态生成输入表单 -->
          <el-form :model="formData" label-width="120px">
            <template v-for="field in form.fields" :key="field?.id">
              <el-form-item :label="field.name" v-if="!field.readOnly">
                <component
                  :is="getFormComponent(field.type)"
                  :model-value="getFieldValue(field)"
                  @update:model-value="(val:any) => updateFieldValue(field, val)"
                  :placeholder="field.placeholder || ''"
                  style="width: 100%"
                ></component>
              </el-form-item>
            </template>
          </el-form>

          <div style="text-align: right; margin-top: 20px">
            <el-button type="primary" @click="handleSubmit">提交</el-button>
          </div>
        </div>

        <!-- ② 没有字段的情况，但有审批按钮 -->
        <div
          v-else-if="form.outcomes && form.outcomes.length && selectedTask.assignee"
          class="outcome-actions"
        >
          <div style="text-align: right; margin-top: 20px">
            <template v-for="outcome in form.outcomes" :key="outcome.name">
              <el-button
                type="primary"
                style="margin-left: 8px"
                @click="handleOutcomeSubmit(outcome)"
              >
                {{ outcome.name }}
              </el-button>
            </template>
          </div>
        </div>

        <el-empty v-else description="该任务没有关联表单"></el-empty>
      </el-card>

      <el-empty v-else description="请选择一个任务" />
    </div>
  </div>
</template>

<script lang="ts" setup>
import { ref, reactive, onMounted, computed } from "vue";
import { FlowableService } from "@/api/flowableService";
import { ElMessage } from "element-plus";

import dayjs from "dayjs";
import relativeTime from "dayjs/plugin/relativeTime";
import "dayjs/locale/zh-cn";
dayjs.extend(relativeTime);
dayjs.locale("zh-cn");

const formatTimeAgo = (time: string) => dayjs(time).fromNow();

interface Props {
  user: {
    name: string;
    password: string;
  };
  taskParam?: any;
}

const props = defineProps<Props>();

const service = new FlowableService(
  "/api/flowable-task/process-api",
  props.user.name,
  props.user.password
);

interface Task {
  id: string;
  name: string;
  assignee: string;
  createTime: string;
  formKey?: string;
}

const tasks = ref<Task[]>([]);
const selectedTask = ref<Task | null>(null);
const form = ref<any>(null);
const formData = reactive<Record<string, any>>({});

const showClaimButton = computed(() => {
  // 任务存在 且 未认领
  const notClaimed = selectedTask.value && !selectedTask.value.assignee;

  // 当前用户角色为主管或经理
  const isManager = ["managers", "leader"].includes(
    props.taskParam?.candidateGroup
  );

  return notClaimed && isManager;
});

// 获取任务列表
async function fetchTasks() {
  tasks.value = await service.listTasks(
    props.taskParam || { assignee: "jack" }
  );

  console.log(props.taskParam?.candidateGroup)
  console.log(tasks.value)

  // 由于任务认领之后tasks集合会变，这里傻瓜式的重新获取一次
  if (tasks.value.length === 0 && props.taskParam?.candidateGroup) {
    tasks.value = await service.listTasks({ assignee: props.user.name });
  }
  // 使用dayjs处理tasks数据中的时间格式
  tasks.value.forEach((task) => {
    task.createTime = dayjs(task.createTime).format("YYYY-MM-DD HH:mm:ss");
  });

  // 删除任务名为空的任务
  // tasks.value = tasks.value.filter((t) => t.name && t.name.trim() !== "");
}

function refresh() {
  fetchTasks();
}

defineExpose({
  refresh,
});

onMounted(() => {
  fetchTasks();
});

async function handleTaskClick(task: Task) {
  // 先清空，避免旧数据渲染
  selectedTask.value = null;
  form.value = null;
  Object.keys(formData).forEach((k) => delete formData[k]);

  try {
    const formRes = await service.getTaskForm(task.id);
    if (formRes && formRes.fields) {
      form.value = formRes;
      formRes.fields.forEach((f: any) => {
        if (f.type === "decimal") {
          formData[f.id] =
            f.value !== undefined && f.value !== "" ? Number(f.value) : null;
        } else {
          formData[f.id] = f.value ?? "";
        }
      });
    } else {
      form.value = null;
    }
    // 等表单数据完全准备好后，再显示选中任务
    selectedTask.value = task;
  } catch (err) {
    ElMessage.error("获取表单失败");
  }
}

function getFormComponent(type: string) {
  switch (type) {
    case "text":
      return "el-input";
    case "decimal":
      return "el-input-number";
    case "multi-line-text":
      return "el-input";
    default:
      return "el-input";
  }
}

function getFieldValue(field: any) {
  const val = formData[field.id];
  if (field.type === "decimal") {
    // ElInputNumber 要求 number 或 null
    if (val === "" || val === undefined) return null;
    const num = Number(val);
    return isNaN(num) ? null : num;
  }
  return val ?? "";
}

function updateFieldValue(field: any, val: any) {
  if (field.type === "decimal") {
    // 反向更新时也保持数值类型
    formData[field.id] = val === null ? "" : Number(val);
  } else {
    formData[field.id] = val;
  }
}

async function handleSubmit() {
  if (!selectedTask.value || !form.value) return;

  // 将 formData 转换成 Flowable API 需要的 properties
  const properties = Object.keys(formData)
    .map((key) => {
      const field = form.value.fields.find((f: any) => f.id === key);
      if (!field) return null;
      return {
        id: field.id,
        name: field.name,
        type: field.type === "decimal" ? "integer" : "string", // decimal 转为 integer
        value: field.type === "decimal" ? Number(formData[key]) : formData[key],
      };
    })
    .filter((item) => item !== undefined) as {
    id: string;
    name: string;
    type: string;
    value: any;
  }[];

  try {
    await service.submitTaskForm({
      taskId: selectedTask.value.id,
      properties,
    });
    ElMessage.success("任务提交成功");

    // 提交成功后刷新任务列表
    refresh();

    // 清空表单
    form.value = null;
    Object.keys(formData).forEach((k) => delete formData[k]);
    selectedTask.value = null;
  } catch (err) {
    console.error(err);
    ElMessage.error("任务提交失败");
  }
}

// 认领任务，刷新表单
async function handleClaimTask() {
  if (!selectedTask.value) return;

  try {
    // 第一步：认领任务
    await service.claimTask(selectedTask.value.id, props.user.name);
    ElMessage.success("任务认领成功");

    // 第二步：更新执行人
    selectedTask.value.assignee = props.user.name;

    // 第三步：获取任务表单
    const formRes = await service.getTaskForm(selectedTask.value.id);
    if (formRes) {
      form.value = formRes;

      // 初始化 formData（如果有字段）
      if (formRes.fields && formRes.fields.length > 0) {
        formRes.fields.forEach((f: any) => {
          if (f.type === "decimal") {
            formData[f.id] =
              f.value !== undefined && f.value !== "" ? Number(f.value) : null;
          } else {
            formData[f.id] = f.value ?? "";
          }
        });
      }
    } else {
      form.value = null;
    }
  } catch (err) {
    console.error(err);
    ElMessage.error("任务认领失败");
  }
}

async function handleOutcomeSubmit(outcome: any) {

  if (!selectedTask.value) return;

  // outcome 对应的字段ID
  // 这个字段ID的规则是：form_{formKey}_outcome，在编写流程时定义的字段名
  const outcomeFieldId = `form_${form.value.key}_outcome`;
  try {
    await service.submitTaskForm({
      taskId: selectedTask.value.id,
      properties: [
        {
          id: outcomeFieldId,
          value: outcome.name,
        },
      ],
    });
    ElMessage.success(`操作成功：${outcome.name}`);
    refresh();
    selectedTask.value = null;
    form.value = null;
  } catch (err) {
    console.error(err);
    ElMessage.error(`操作失败：${outcome.name}`);
  }
}
</script>

<style scoped>
.flowable-page {
  display: flex;
  height: 100%;
  gap: 20px;
  padding: 20px;
}

.card-header {
  display: flex;
  justify-content: space-between;
  align-items: center;
  margin-bottom: 10px;
}

.outcome-actions {
  display: flex;
  justify-content: flex-end;
  gap: 10px;
}

.task-list {
  width: 35%;
}

.task-detail {
  flex: 1;
}

.list-card,
.detail-card {
  height: 100%;
}
</style>
